#include "referee.h"
#include "string.h"
#include "stdio.h"
#include "CRC8_CRC16.h"
#include "protocol.h"
#include "arm_math.h"
#include "chassis_task.h"

frame_header_struct_t referee_receive_header;
frame_header_struct_t referee_send_header;

ext_game_status_t game_state_t;                                         // 0x0001
ext_game_result_t game_result_t;                                        // 0x0002
ext_game_robot_HP_t game_robot_HP_t;                                    // 0x0003

ext_event_data_t field_event_t;                                         // 0x0101
ext_supply_projectile_action_t supply_projectile_action_t;              // 0x0102
ext_supply_projectile_booking_t supply_projectile_booking_t;            // 0x0103
ext_referee_warning_t referee_warning_t;                                // 0x0104
ext_dart_remaining_time_t dart_remaining_time;                          // 0x0105

ext_game_robot_status_t robot_state_t;                                  // 0x0201
ext_power_heat_data_t power_heat_data_t;                                // 0x0202
ext_game_robot_pos_t game_robot_pos_t;                                  // 0x0203
ext_buff_t buff_musk_t;                                                 // 0x0204
aerial_robot_energy_t robot_energy_t;                                   // 0x0205
ext_robot_hurt_t robot_hurt_t;                                          // 0x0206
ext_shoot_data_t shoot_data_t;                                          // 0x0207
ext_bullet_remaining_t bullet_remaining_t;                              // 0x0208
ext_rfid_status_t rfid_status_t;                                        // 0x0209
ext_dart_client_t dart_client_t;                                        // 0x020A
ext_ground_robot_position_t ground_robot_position_t;                    // 0x020B
ext_radar_mark_data_t radar_mark_data_t;                                // 0x020C
ext_sentry_info_t sentry_info_t;                                        // 0x020D
ext_radar_info_t radar_info_t;                                          // 0x020E
ext_student_interactive_header_data_t student_interactive_data_t;
ext_map_data_t map_data_t;

battle_status_t battle_status;

void init_referee_struct_data(void)
{
    memset(&referee_receive_header, 0, sizeof(frame_header_struct_t));
    memset(&referee_send_header, 0, sizeof(frame_header_struct_t));

    memset(&game_state_t, 0, sizeof(ext_game_status_t));
    memset(&game_result_t, 0, sizeof(ext_game_result_t));
    memset(&game_robot_HP_t, 0, sizeof(ext_game_robot_HP_t));


    memset(&field_event_t, 0, sizeof(ext_event_data_t));
    memset(&supply_projectile_action_t, 0, sizeof(ext_supply_projectile_action_t));
    memset(&supply_projectile_booking_t, 0, sizeof(ext_supply_projectile_booking_t));
    memset(&referee_warning_t, 0, sizeof(ext_referee_warning_t));
    memset(&dart_remaining_time, 0, sizeof(ext_dart_remaining_time_t));


    memset(&robot_state_t, 0, sizeof(ext_game_robot_status_t));
    memset(&power_heat_data_t, 0, sizeof(ext_power_heat_data_t));
    memset(&game_robot_pos_t, 0, sizeof(ext_game_robot_pos_t));
    memset(&buff_musk_t, 0, sizeof(ext_buff_t));
    memset(&robot_energy_t, 0, sizeof(aerial_robot_energy_t));
    memset(&robot_hurt_t, 0, sizeof(ext_robot_hurt_t));
    memset(&shoot_data_t, 0, sizeof(ext_shoot_data_t));
    memset(&bullet_remaining_t, 0, sizeof(ext_bullet_remaining_t));
    memset(&rfid_status_t, 0, sizeof(ext_rfid_status_t));
    memset(&dart_client_t, 0, sizeof(ext_dart_client_t));
    memset(&ground_robot_position_t, 0, sizeof(ext_ground_robot_position_t));
    memset(&radar_mark_data_t, 0, sizeof(ext_radar_mark_data_t));
    memset(&sentry_info_t, 0, sizeof(ext_sentry_info_t));
    memset(&radar_info_t, 0, sizeof(ext_radar_info_t));


    memset(&student_interactive_data_t, 0, sizeof(ext_student_interactive_header_data_t));
    memset(&map_data_t, 0, sizeof(ext_map_data_t));

}
uint16_t cmd_id = 0;
void referee_data_solve(uint8_t *frame)
{
    

    uint8_t index = 0;

    memcpy(&referee_receive_header, frame, sizeof(frame_header_struct_t));

    index += sizeof(frame_header_struct_t);

    memcpy(&cmd_id, frame + index, sizeof(uint16_t));
    index += sizeof(uint16_t);

    switch (cmd_id)
    {
        case GAME_STATE_CMD_ID:
        {
            memcpy(&game_state_t, frame + index, sizeof(game_state_t));
        }
        break;

        // case GAME_RESULT_CMD_ID:
        // {
        //     memcpy(&game_result_t, frame + index, sizeof(game_result_t));
        // }
        // break;

        case GAME_ROBOT_HP_CMD_ID:
        {
            memcpy(&game_robot_HP_t, frame + index, sizeof(game_robot_HP_t));
        }
        break;

        // case FIELD_EVENTS_CMD_ID:
        // {
        //     memcpy(&field_event_t, frame + index, sizeof(field_event_t));
        // }
        // break;

        // case SUPPLY_PROJECTILE_ACTION_CMD_ID:
        // {
        //     memcpy(&supply_projectile_action_t, frame + index, sizeof(supply_projectile_action_t));
        // }
        // break;

        // case SUPPLY_PROJECTILE_BOOKING_CMD_ID:
        // {
        //     memcpy(&supply_projectile_booking_t, frame + index, sizeof(supply_projectile_booking_t));
        // }
        // break;

        // case REFEREE_WARNING_CMD_ID:
        // {
        //     memcpy(&referee_warning_t, frame + index, sizeof(referee_warning_t));
        // }
        // break;
        //
        //  case DART_INFO_CMD_ID:
        // {
        //     memcpy(&dart_remaining_time, frame + index, sizeof(dart_remaining_time));
        // }
        // break;

        case ROBOT_STATE_CMD_ID:
        {
            memcpy(&robot_state_t, frame + index, sizeof(robot_state_t));
        }
        break;

        case POWER_HEAT_DATA_CMD_ID:
        {
            memcpy(&power_heat_data_t, frame + index, sizeof(power_heat_data_t));
        }
        break;

        case ROBOT_POS_CMD_ID:
        {
            memcpy(&game_robot_pos_t, frame + index, sizeof(game_robot_pos_t));
        }
        break;

        case BUFF_MUSK_CMD_ID:
        {
            memcpy(&buff_musk_t, frame + index, sizeof(buff_musk_t));
        }
        break;

        case AERIAL_ROBOT_ENERGY_CMD_ID:
        {
            memcpy(&robot_energy_t, frame + index, sizeof(robot_energy_t));
        }
        break;

        case ROBOT_HURT_CMD_ID:
        {
            memcpy(&robot_hurt_t, frame + index, sizeof(robot_hurt_t));
        }
        break;

        case SHOOT_DATA_CMD_ID:
        {
            memcpy(&shoot_data_t, frame + index, sizeof(shoot_data_t));
        }
        break;

        case BULLET_REMAINING_CMD_ID:
        {
            memcpy(&bullet_remaining_t, frame + index, sizeof(bullet_remaining_t));
        }
        break;

        // case RFID_STATUS_CMD_ID:
        // {
        //     memcpy(&rfid_status_t, frame + index, sizeof(rfid_status_t));
        // }
        // break;

        // case DART_CLIENT_CMD_ID:
        // {
        //     memcpy(&dart_client_t, frame + index, sizeof(dart_client_t));
        // }
        // break;

        case GROUND_ROBOT_POSITION_CMD_ID:
        {
            memcpy(&ground_robot_position_t, frame + index, sizeof(ground_robot_position_t));
        }
        break;

        // case RADAR_MARK_DATA_CMD_ID:
        // {
        //     memcpy(&radar_mark_data_t, frame + index, sizeof(radar_mark_data_t));
        // }
        // break;

        case SENTRY_INFO_CMD_ID:
        {
            memcpy(&sentry_info_t, frame + index, sizeof(sentry_info_t));
        }
        break;

        // case RADAR_INFO_CMD_ID:
        // {
        //     memcpy(&radar_info_t, frame + index, sizeof(radar_info_t));
        // }
        // break;

        case STUDENT_INTERACTIVE_DATA_CMD_ID:
        {
            memcpy(&student_interactive_data_t, frame + index, sizeof(student_interactive_data_t));
        }
        break;

        case CLIENT_SIDE_MINIMAP_DATA_CMD_ID:
        {
            memcpy(&map_data_t, frame + index, sizeof(map_data_t));
        }
        break;

        default:
        {
            break;
        }
    }
}

void get_chassis_power_and_buffer(fp32 *power, uint16_t *buffer)
{
    *power = power_heat_data_t.chassis_power;
    *buffer = power_heat_data_t.buffer_energy;
}

void get_robot_id(uint16_t *robot_id, uint16_t *client_id)
{
    *robot_id = robot_state_t.robot_id;
     *client_id = robot_state_t.robot_id + 256;
}

void robot_id(uint16_t *robot_id)
{
    *robot_id = robot_state_t.robot_id;
}

void get_shoot_heat1_limit_and_heat1(uint16_t *heat1_limit, uint16_t *heat1)
{
    *heat1_limit = robot_state_t.shooter_barrel_heat_limit;
    *heat1 = power_heat_data_t.shooter_id1_17mm_cooling_heat;
}

void get_shoot_heat2_limit_and_heat2(uint16_t *heat2_limit, uint16_t *heat2)
{
    *heat2_limit = robot_state_t.shooter_barrel_heat_limit;
    *heat2 = power_heat_data_t.shooter_id2_17mm_cooling_heat;
}

void get_chassis_power_limit(uint16_t *power_limit)
{
    *power_limit = robot_state_t.chassis_power_limit;
}

void get_robot_hurt(uint8_t *armor_id, uint8_t *hurt_type)
{
    *armor_id = robot_hurt_t.armor_id;
    *hurt_type = robot_hurt_t.HP_deduction_reason;
}

void get_robot_level(uint8_t *level)
{
    *level = robot_state_t.robot_level;
}

void get_ammo(uint16_t *bullet_remaining)
{
    *bullet_remaining = bullet_remaining_t.projectile_allowance_17mm;
}

void get_sentry_HP(uint16_t *sentry_HP)
{
    if(robot_state_t.robot_id < 100)
    {
        *sentry_HP = game_robot_HP_t.red_7_robot_HP;
    }
    else
    {
        *sentry_HP = game_robot_HP_t.blue_7_robot_HP;
    }
}

fp32 armor_direction(uint8_t armor_type)
{
    static fp32 direction;
    if(robot_hurt_t.HP_deduction_reason == 0x0)
    {
        switch(armor_type)
        {
            case 0:
                direction = rad_format(-chassis_move.chassis_radar_yaw_motor.gimbal_mit_motor_measure->pos + PI / 2);
             break;

            case 1:
                direction = rad_format(-chassis_move.chassis_radar_yaw_motor.gimbal_mit_motor_measure->pos - PI);
            break;

            case 2:
                direction = -chassis_move.chassis_radar_yaw_motor.gimbal_mit_motor_measure->pos;
            break;

            case 3:
                direction = rad_format(-chassis_move.chassis_radar_yaw_motor.gimbal_mit_motor_measure->pos - PI / 2);
            break;
        }
    }
    return direction;
}

void referee_battle_status_update(battle_status_t *referee_battle_status)
{
    referee_battle_status->supply_zone_non_overlap = (field_event_t.event_type & (1 << 0)) != 0;
    referee_battle_status->supply_zone_overlap = (field_event_t.event_type & (1 << 1)) != 0;
    referee_battle_status->supply_zone_occupied = (field_event_t.event_type & (1 << 2)) != 0;

    // --- 解析bit 3-5 ---
    referee_battle_status->small_energy_activated = (field_event_t.event_type & (1 << 3)) != 0;
    referee_battle_status->large_energy_activated = (field_event_t.event_type & (1 << 4)) != 0;
    referee_battle_status->central_highland_status = (field_event_t.event_type >> 5) & 0x03; // 取bit5-6

    // --- 解析bit 7-8 ---
    referee_battle_status->trapezoid_highland_occupied = (field_event_t.event_type & (0x03 << 7)) != 0;

    // --- 解析bit 9-17 ---
    referee_battle_status->last_hit_time = (field_event_t.event_type >> 9) & 0x3FF; // 取9位（0-511，实际范围0-420）

    // --- 解析bit 18-20 ---
    referee_battle_status->last_hit_target = (field_event_t.event_type >> 18) & 0x07;

    // --- 解析bit 21-22 ---
    referee_battle_status->center_zone_status = (field_event_t.event_type >> 21) & 0x03;

    // --- 保留位 ---
    referee_battle_status->reserved = (field_event_t.event_type >> 23) & 0x1FF;
}

const ext_game_robot_status_t *get_game_robot_status_point(void)
{
    return &robot_state_t;
}

const ext_robot_hurt_t *get_robot_hurt_point(void)
{
    return &robot_hurt_t;
}
